<!--
 * Copyright © 2022
 * @Author: zhangxiang
 * @Date: 2022-11-21 15:04:05
 * @LastEditors: zhangxiang
 * @LastEditTime: 2023-09-18 16:22:47
 * @Description:
 *
-->

<template>
  <el-dialog
    class="service-deployment-dialog"
    title="微服务部署进度"
    :visible="show"
    width="80vw"
    top="15vh"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    @close="closeClick"
  >
    <ServiceDeploymentV2
      :micro-service="microService"
      :stage-info="stageInfo"
    />
    <!-- 操作按钮 -->
    <div slot="footer" class="dialog-footer">
      <el-button size="small" @click="cancelClick">取 消</el-button>
      <el-button
        type="primary"
        size="small"
        @click="cancelClick"
      >确 定</el-button>
    </div>
  </el-dialog>
</template>

<script>
import ServiceDeploymentV2 from '../components/ServiceDeploymentV2.vue'
import { getDeployServiceStageInfo } from '@/api/cnap/app-service'
import {
  DEPLOY_STAGE_STEP_NUMS,
  DEPLOY_STAGE_STEP_NUMS_GPU,
  GPU_BUSINESS_SCENE,
  DEPLOY_STAGE_TITLES,
  DEPLOY_STAGE_DEFAULT_INFO
} from '@/utils/cnap/constant'

const POLLING_INTERVAL = 1000

/**
 * @description: 获取默认数据
 * @return {*}
 */
const getDefaultStageInfo = () => {
  return DEPLOY_STAGE_DEFAULT_INFO
}

export default {
  name: 'ServiceDeploymentDialog',
  components: {
    ServiceDeploymentV2
  },
  props: {
    // 显示
    show: {
      type: Boolean,
      default: false
    },
    // 微服务
    microService: {
      type: Object,
      default: () => {}
    }
  },
  data() {
    return {
      timerPolling: null,
      stageInfo: getDefaultStageInfo()
    }
  },
  computed: {},
  destroyed() {
    if (this.timerPolling) {
      clearTimeout(this.timerPolling)
      this.timerPolling = null
    }
  },
  created() {
    this.initData()
  },
  methods: {
    /**
     * @description: 是GPU
     * @param {*} scheduleStrategy
     * @return {*}
     */
    isGPU(scheduleStrategy) {
      return (
        scheduleStrategy &&
        scheduleStrategy.businessScene &&
        scheduleStrategy.businessScene.svcType === GPU_BUSINESS_SCENE
      )
    },
    /**
     * @description: 轮询获取阶段信息
     * @return {*}
     */
    pollingStageInfo() {
      // 请求接口
      getDeployServiceStageInfo(this.microService.svcId)
        .then((res) => {
          const isGPU = this.isGPU(this.microService.scheduleStrategy) // 是否GPU场景
          const stageStepNums = isGPU
            ? DEPLOY_STAGE_STEP_NUMS_GPU
            : DEPLOY_STAGE_STEP_NUMS // 阶段数
          // 查找相应微服务的阶段信息
          let complete = true
          const stageInfo = res.data
          // 存在相应微服务阶段信息
          if (stageInfo) {
            const tempStageInfo = {}
            let svcSuccess = true // 微服务是否部署成功
            let svcError = false // 微服务是否部署失败
            const stageKes = [
              'firstStages',
              'secondStages',
              'thirdStages',
              'fourthStages'
            ]
            let currentStage = 1
            stageKes.forEach((key, index) => {
              let stageStatus = 0 // 0-未部署 1-部署中 2-部署失败 3-部署成功
              if (Array.isArray(stageInfo[key]) && stageInfo[key].length > 0) {
                stageStatus = 1
                const isError = stageInfo[key].some((item) => {
                  return !item.success // 阶段的步骤信息存在不成功 则这个阶段不成功
                })
                if (isError) {
                  stageStatus = 2
                }
                if (stageInfo[key].length === stageStepNums[index]) {
                  const isSuccess = stageInfo[key].every((item) => {
                    return item.success // 阶段的步骤信息都成功 则这个阶段成功
                  })
                  if (isSuccess) {
                    stageStatus = 3
                  }
                }
              }
              // 判断当前阶段
              if (stageStatus === 1) {
                currentStage = index + 1
              } else if (stageStatus === 2) {
                currentStage = index + 1
              } else if (stageStatus === 3) {
                currentStage = Math.min(index + 2, 4)
              }
              tempStageInfo[key] = {
                title: DEPLOY_STAGE_TITLES[index],
                stageStatus: stageStatus, // 阶段部署状态
                stepTotal: stageStepNums[index], // 阶段步骤总数
                steps: stageInfo[key] || [] // 阶段步骤详细信息
              }
              // 每个阶段都需要成功 微服务部署才成功
              svcSuccess = svcSuccess && stageStatus === 3
              // 有一个阶段成功 微服务部署都算失败
              svcError = svcError || stageStatus === 2
            })
            // 更新当前阶段
            tempStageInfo['currentStage'] = currentStage
            // 当前阶段刚开始时，无法判断，通过currentStage判断补全状态
            if (tempStageInfo[stageKes[currentStage - 1]].stageStatus === 0) {
              tempStageInfo[stageKes[currentStage - 1]].stageStatus = 1
            }
            // 设置微服务部署状态
            tempStageInfo['svcStatus'] = svcError ? 2 : svcSuccess ? 3 : 1
            this.stageInfo = tempStageInfo
            // 每个微服务都部署成功 才算结束
            complete = complete && svcSuccess
          } else {
            this.stageInfo = getDefaultStageInfo()
            complete = false
          }
          if (complete) {
            // 完成
            if (this.timerPolling) {
              clearTimeout(this.timerPolling)
              this.timerPolling = null
            }
          } else {
            // 未完成
            this.timerPolling = setTimeout(() => {
              this.pollingStageInfo()
            }, POLLING_INTERVAL)
          }
        })
        .catch((err) => {
          console.log(err)
        })
    },
    /**
     * @description: 初始化
     * @return {*}
     */
    initData() {
      this.pollingStageInfo()
    },
    /**
     * @description: 关闭
     * @return {*}
     */
    closeClick() {
      this.$emit('update:show', false)
    },
    /**
     * @description: 取消
     * @return {*}
     */
    cancelClick() {
      this.closeClick()
      this.$emit('cancel')
    }
  }
}
</script>
<style lang="less" scoped></style>
